package com.yn.common.util;

import com.yn.common.entity.ApkInfoDO;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import net.dongliu.apk.parser.ApkFile;
import net.dongliu.apk.parser.bean.ApkMeta;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author YN
 */
public class FileUtil {

    /**
     * 计算MultipartFile文件的MD5摘要。
     * @param file MultipartFile文件。
     * @return 文件的MD5摘要字符串。
     * @throws IOException 如果读取文件时发生错误。
     * @throws NoSuchAlgorithmException 如果MD5算法不可用。
     */
    public static String calculateMD5(MultipartFile file) throws IOException, NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("MD5");
        byte[] buffer = new byte[8192];
        int read;
        InputStream is = file.getInputStream();
        while ((read = is.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }
        byte[] md5sum = digest.digest();
        BigInteger bigInt = new BigInteger(1, md5sum);
        // 格式化为16进制的字符串
        return String.format("%032x", bigInt);
    }

    public static String calculateMD5(InputStream inputStream) throws IOException, NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("MD5");
        byte[] buffer = new byte[8192];
        int read;
        while ((read = inputStream.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }
        byte[] md5sum = digest.digest();
        BigInteger bigInt = new BigInteger(1, md5sum);
        return String.format("%032x", bigInt);
    }


    /**
     * 计算MultipartFile文件的SHA-256摘要。
     * @param file MultipartFile文件。
     * @return 文件的SHA-256摘要字符串。
     * @throws IOException 如果读取文件时发生错误。
     * @throws NoSuchAlgorithmException 如果SHA-256算法不可用。
     */
    public static String calculateSHA256(MultipartFile file) throws IOException, NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] buffer = new byte[8192];
        int read;
        InputStream is = file.getInputStream();
        while ((read = is.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }
        byte[] sha256sum = digest.digest();
        BigInteger bigInt = new BigInteger(1, sha256sum);
        // 格式化为16进制的字符串
        return String.format("%064x", bigInt);
    }


    /**
     * 提取apk文件信息
     * @param multipartFile 文件
     * @return ApkInfoDO
     * @throws IOException 如果解析文件出错
     */
    public static ApkInfoDO parseApk(MultipartFile multipartFile) throws IOException {
        Path tempFile = Files.createTempFile(null, null);
        try {
            // 保存上传文件到临时文件
            multipartFile.transferTo(tempFile.toFile());
            // 使用 try-with-resources 确保 ApkFile 资源被正确关闭
            try (ApkFile apkParser = new ApkFile(tempFile.toFile())) {
                ApkMeta apkMeta = apkParser.getApkMeta();
                ApkInfoDO ApkInfoDO = new ApkInfoDO();
                ApkInfoDO.setPackageName(apkMeta.getPackageName());
                ApkInfoDO.setName(apkMeta.getName());
                ApkInfoDO.setVersions(apkMeta.getVersionName());
                if (apkParser.getIconFile()!=null){
                    byte[] iconData = apkParser.getIconFile().getData();
                    // 将字节数据编码为Base64字符串
                    String base64Icon = Base64.getEncoder().encodeToString(iconData);
                    ApkInfoDO.setLogo(base64Icon);
                }
                return ApkInfoDO;
            }
        } finally {
            // 在 finally 块中尝试删除临时文件以确保文件被删掉
            try {
                Files.deleteIfExists(tempFile);
            } catch (IOException e) {
                // 日志处理或额外的异常处理
                e.printStackTrace();
            }
        }
    }


    public static ApkInfoDO parseApk(InputStream inputStream) throws IOException {
        try (ApkFile apkParser = new ApkFile(String.valueOf(inputStream))) {
            ApkMeta apkMeta = apkParser.getApkMeta();
            ApkInfoDO ApkInfoDO = new ApkInfoDO();
            ApkInfoDO.setPackageName(apkMeta.getPackageName());
            ApkInfoDO.setName(apkMeta.getName());
            ApkInfoDO.setVersions(apkMeta.getVersionName());
            if (apkParser.getIconFile() != null) {
                byte[] iconData = apkParser.getIconFile().getData();
                // 将字节数据编码为Base64字符串
                String base64Icon = Base64.getEncoder().encodeToString(iconData);
                ApkInfoDO.setLogo(base64Icon);
            }
            return ApkInfoDO;
        }
    }


    public static ApkInfoDO parseApk(File apkFile) throws IOException {
        try (ApkFile apkParser = new ApkFile(apkFile)) {
            ApkMeta apkMeta = apkParser.getApkMeta();
            ApkInfoDO ApkInfoDO = new ApkInfoDO();
            ApkInfoDO.setPackageName(apkMeta.getPackageName());
            ApkInfoDO.setName(apkMeta.getName());
            ApkInfoDO.setVersions(apkMeta.getVersionName());
            if (apkParser.getIconFile() != null) {
                byte[] iconData = apkParser.getIconFile().getData();
                // 将字节数据编码为Base64字符串
                String base64Icon = Base64.getEncoder().encodeToString(iconData);
                ApkInfoDO.setLogo(base64Icon);
            }
            return ApkInfoDO;
        }
    }

}